/*
 * BPlusNode.cpp
 *
 *  Created on: 09/11/2013
 *      Author: gastonmontes
 */

#include "BPlusNode.h"

#pragma mark - Private methods.
template<class T>
void BPlusNode<T>::clear() {
	typename RecordList::iterator it;
	for (it = records.begin(); it != records.end(); ++it) {
		delete *it;
	}
	records.clear();
	position = records.end();
	elementsCount = 0;
}

#pragma mark - Constructor and Destructor methods.

template<class T>
BPlusNode<T>::BPlusNode(BigInt nodeNivel) {
	position = records.begin();
	level = nodeNivel;
	elementsCount = 0;
}

template<class T>
BPlusNode<T>::~BPlusNode() {
	clear();
}

#pragma mark - ABM implementation.

template<class T>
void BPlusNode<T>::add(const T& record) {
	records.push_back(new T(record));
	position = records.begin();
	++elementsCount;
}

template<class T>
bool BPlusNode<T>::find(T& record, const IEvaluator<T>& eval) {
	typename RecordList::iterator it;
	for (it = records.begin(); it != records.end(); ++it) {
		if (eval.eval(**it) == 0) {
			record = **it;
			return true;
		}
	}
	return false;
}

template<class T>
bool BPlusNode<T>::next(T& record) {
	if (position == records.end())
		return false;
	record = **position;
	++position;
	return true;
}

template<class T>
bool BPlusNode<T>::remove(const T& record) {
	typename RecordList::iterator it;
	for (it = records.begin(); it != records.end(); ++it) {
		if (**it == record) {
			delete *it;
			records.erase(it);
			--elementsCount;
			return true;
		}
	}
	return false;
}

#pragma mark - ISerializable implementation.

template<class T>
BigInt BPlusNode<T>::size() const {
	BigInt total = sizeof(BigInt) * 2;  // Metadata size: nivel size and elements count size.
	T* record;
	typename RecordList::const_iterator it;
	for (it = records.begin(); it != records.end(); ++it) {
		record = *it;
		total += record->size();
	}
	return total;
}

template<class T>
void BPlusNode<T>::serialize(ISerializer& serializer) const {
	serializer.serializeUnsignedLongInt(level); // Serialize the nivel.
	serializer.serializeUnsignedLongInt(elementsCount); // Elements count.
	T* record;
	typename RecordList::const_iterator it;
	for (it = records.begin(); it != records.end(); ++it) {
		record = *it;
		record->serialize(serializer);
	}
}

template<class T>
void BPlusNode<T>::unserialize(IUnserializer& unserializer) {
	clear();
	level = unserializer.unserializeUnsignedLongInt();
	elementsCount = unserializer.unserializeUnsignedLongInt();
	T* record;
	for (BigInt x = 0; x < elementsCount; x++) {
		record = new T();
		record->unserialize(unserializer);
		records.push_back(record);
	}
	position = records.begin();
}

#pragma mark - Level methods.

template<class T>
void BPlusNode<T>::upLevel() {
	++level;
}

template<class T>
void BPlusNode<T>::downLevel() {
	--level;
}

